///////////////////////////////////////////////////////////
///////////////// Have an itch? Scratch it! ///////////////
///////////////////////// SCRATCH /////////////////////////
/////////////////////  A MUD  Server   ////////////////////
///////////////////// By: Jared Devall ////////////////////
/////////////////////      Thanks:     ////////////////////
/////////////////////  DIKU/Merc/ROM   ////////////////////
///////////////////// Aetas/Deus Gang  ////////////////////
/////////////////////       Beej       ////////////////////
///////////////////////////////////////////////////////////

#ifndef __WORLD_H_
#define __WORLD_H_

#include "definitions.h"
#include <list>
#include "timer.h"
#include "area.h"
#include "mob.h"
#include "character.h"
#include "random.h"
#include "help.h"
#include "board.h"

class World {
	private:
		bool	_worldExists;
		void	FlushOutput();
		void	UpdateCharacters();
		void	UpdateMobs();
		void	KillFlaggedCharacters();
		void	HandleInput();
		void	UpdateTimers();
		void	Schedule( Timer* );
		void	Unschedule( Timer* );
		void	loadHelp();
		void	saveHelp();
		void	saveBoards();
		void	loadBoards();
		int		_index;
		std::string _version;
		std::list< Timer* >		_timers;
		std::list< Help* >		_helpList;
		std::list< Board* >		_boards;
		std::list< Character* > _cList;
		std::list< Mob* >		_mList;
		std::list< Object* >	_oList;
		std::list< Area* >		_areas;
		std::list< std::string* > _banList;

	public:
		Character*	FindCharacter( const std::string& );
		Mob*		FindMob( const std::string& );
		Mob*		FindMob( int );
		Room*		FindRoom( int );
		void	Broadcast( const std::string&, int );
		void	Omninet( const std::string&, int = STANDARD, Character* = NULL, bool = false );
		void	Exist( const std::string&, int port, bool copyover );
		void	Die( void );
		void	Copyover( void );
		void	CopyoverRecovery( void );
		void	Monitor( void );
		void	getServerData();
		void	saveServerData();
		static World& Instance();
		void	getBanner( std::string& );
		void	setIndex( int );
		int		getIndex();
		int		incrementIndex();
		Area*	findParentArea( int );
		std::list< Help* >&			getHelpList();
		std::string					getHelp( std::string );
		std::list< std::string* >&	getBanList();
		void						addBannedIp( std::string );
		bool						isBanned( std::string );
		std::list< Board* >&		getBoards();
		Board*						addBoard();
		std::list< Character* >&	getClist();
		std::list< Mob* >&			getMlist();
		std::list< Object* >&		getOlist();
		void	setVersion( std::string );
		std::string getVersion();
		std::list< Area* >& getAreas();
		std::list< Timer* >& getTimers();
		Area*	getArea( int );
		//Area*	SetArea( int, Area& );
		Area*	addArea();
		//void	AddAreas( int );
		void	Save();
		void	Load();
};

// Our singleton instance
inline World &World::Instance() {
	static World instance;
	return instance;
}

#endif
